#ifndef TC_ALLOCATOR_HPP
#define TC_ALLOCATOR_HPP

/** \file Allocator.hpp
 * Declarations for the templated class Allocator.
 *
 * (C) Copyright  Semih Cemiloglu
 * All rights reserved, see COPYRIGHT file for details.
 *
 * (C) Copyright Nicolai M. Josuttis 1999.
 * Permission to copy, use, modify, sell and distribute this software
 * is granted provided this copyright notice appears in all copies.
 * This software is provided "as is" without express or implied
 * warranty, and with no claim as to its suitability for any purpose.
 *
 * $Id: Allocator.hpp 117 2006-06-19 06:49:41Z semihc $
 *
 * Partly derived from N.M.Josuttis' work:
 * "The C++ Standard Library - A Tutorial and Reference"
 * by Nicolai M. Josuttis, Addison-Wesley, 1999
 *
 */



#include <cstddef>
#include "Global.hh"


namespace TC {

  TC_EXPORT template <typename T>
  class Allocator 
  {
  public:
    // type definitions
    typedef T        value_type;
    typedef T*       pointer;
    typedef const T* const_pointer;
    typedef T&       reference;
    typedef const T& const_reference;
    typedef std::size_t    size_type;
    typedef std::ptrdiff_t difference_type;

    // rebind allocator to type U
    template <class U>
    struct rebind {
      typedef Allocator<U> other;
    };

    // return address of values
    pointer address(reference value) const {
      return &value;
    }
  
    const_pointer address(const_reference value) const {
      return &value;
    }

    /* constructors and destructor
     * - nothing to do because the allocator has no state
     */
    Allocator() throw() {}
    ~Allocator() throw() {}
    Allocator(const Allocator&) throw() {}
    template <class U>
    Allocator(const Allocator<U>&) throw() {}


    // Return maximum number of elements that can be allocated
    size_type max_size() const; // throw()
    // Overloaded version to resolve Sun-Forte issues
    size_type max_size (size_type size) const; // throw()

    // allocate but don't initialize num elements of type T
    pointer allocate(size_type num, const void* ptr = 0);

    // initialize elements of allocated storage p with value value
    void construct(pointer p, const T& value);

    // destroy elements of initialized storage p
    void destroy(pointer p);

    // deallocate storage p of deleted elements
    void deallocate(pointer p, size_type num);

  }; // end class


  // return that all specializations of this allocator 
  // are interchangeable
  template <class T1, class T2>
  bool operator==(const Allocator<T1>&,
                  const Allocator<T2>&) // throw() 
  {
    return true;
  }

  template <class T1, class T2>
  bool operator!=(const Allocator<T1>&,
                  const Allocator<T2>&) // throw() 
  {
    return false;
  }

} // end namespace


#ifndef TC_TEMPLATE_DEFS_SEPARATE
# include "Allocator.cpp"
#endif


#endif /* TC_ALLOCATOR_HPP */
